/*
 * Robot12API.cpp
 *
 *  Created on: 17/11/2013
 *      Author: gonzalo
 */

#include "Robot12API.h"

Robot12API::Robot12API(AdminKeys adminKeys, string hostName){
	comRobot12 = new middleware::CommunicationRobot12(adminKeys.getRobot12Key());
	comRobot11 = new middleware::CommunicationRobot11(adminKeys.getRobot11Key());
	comAgv = new middleware::CommunicationAGV(adminKeys.getAgvKey(),hostName);
	comCinta = new middleware::CommunicationPrimerCinta(adminKeys.getCintaKey());
	comCanastos = new middleware::CommunicationCanastos(adminKeys.getCanastosKey());
}

void Robot12API::procesarProducto(Producto prod) {
	CLogger::log("Procesar producto " + StringUtils::itos(prod.productoId), LogLevelEnum::INFO);
	this->comRobot12->setProcesando();
	std::map<TipoPieza, int> piezasCantidad = MapaPiezasProducto::obtenerPiezasYCantidad(prod.tipo);
	std::map<TipoPieza, int>::iterator it;
	for (it = piezasCantidad.begin(); it != piezasCantidad.end(); it++) {
		TipoPieza pieza = (*it).first;
		int cantidad = (*it).second;
		CLogger::log("Colocando la pieza " + StringUtils::itos(pieza) + "("+StringUtils::itos(cantidad)+")", LogLevelEnum::INFO);
		comCanastos->marcarUso(pieza);
		Random::msleep(500, 800);

		if (comCanastos->getEstadoCanasto(pieza).ausente){
			comAgv->agregarPedidoCanastos(this->buildPedidoPiezas(pieza));
			comCanastos->agregarEsperaDePieza(pieza);
			CLogger::log("Falta el canasto " + StringUtils::itos(pieza) + ", esperando al AGV.", LogLevelEnum::INFO);
			comRobot12->esperarPieza();
		}
		int restante = cantidad;
		/* Si no me alcanzan las piezas se las pido al AGV */
		while ((restante = comCanastos->usarCantidad(pieza, abs(restante))) < 0) {
			comAgv->agregarPedidoCanastos(this->buildPedidoPiezas(pieza));
			comCanastos->agregarEsperaDePieza(pieza);
			CLogger::log("Faltan piezas del canasto "+StringUtils::itos(pieza)+", esperando al AGV.", LogLevelEnum::INFO);
			comRobot12->esperarPieza();
		}

		comCanastos->desmarcarUso(pieza);
	}
	CLogger::log("Termina de procesar producto " + StringUtils::itos(prod.productoId), LogLevelEnum::INFO);
	this->comRobot12->setListo();
	this->comRobot11->robot12EstaListo();
}

PedidoPiezas Robot12API::buildPedidoPiezas(TipoPieza pieza){
	PedidoPiezas pedido;
	memset((void*)pedido.piezas, 0, MAX_PIEZAS * sizeof(int));
	pedido.piezas[0] = pieza;
	return pedido;
}

Producto Robot12API::obtenerProducto() {
	this->comRobot12->esperarCinta();
	return this->comCinta->obtenerProducto();
}

Robot12API::~Robot12API() {
	delete comRobot12;
	delete comRobot11;
	delete comAgv;
	delete comCinta;
	delete comCanastos;

}
